﻿using Microsoft.Extensions.Caching.Distributed;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using TomNet.Caching;

namespace TomNet.App.WebApi.Common
{
    public class VirtualCurrencyData
    {
        private IHttpClientFactory _httpClientFactory;
        private IDistributedCache _cache;
        public VirtualCurrencyData(IHttpClientFactory httpClientFactory, IDistributedCache cache)
        {
            _httpClientFactory = httpClientFactory;
            _cache = cache;
        }
        /// <summary>
        /// 币种详情
        /// </summary>
        /// <param name="CurrencyId"></param>
        private ApiResult<Coin> GetPowCoinDetails(int CurrencyId)
        {
            using (var client = _httpClientFactory.CreateClient())
            {
                List<KeyValuePair<String, String>> paramList = new List<KeyValuePair<String, String>>();
                paramList.Add(new KeyValuePair<string, string>("CurrencyId", CurrencyId.ToString()));
                HttpContent httpContent = new FormUrlEncodedContent(paramList);
                var result = client.PostAsync("http://47.110.252.85:8011/API/APP/PowCoinDetails", httpContent).Result;
                var d = result.Content.ReadAsStringAsync().Result;
                var data = JsonConvert.DeserializeObject<ApiResult<Coin>>(d);
                return data;
            }
        }
        /// <summary>
        /// 线形图
        /// </summary>
        /// <param name="CurrencyId"></param>
        private ApiResult<ChartDatas> GetPowCoinChart(string Code, int Day = 30)
        {
            using (var client = _httpClientFactory.CreateClient())
            {
                List<KeyValuePair<String, String>> paramList = new List<KeyValuePair<String, String>>();
                paramList.Add(new KeyValuePair<string, string>("Code", Code));
                paramList.Add(new KeyValuePair<string, string>("Day", Day.ToString()));
                HttpContent httpContent = new FormUrlEncodedContent(paramList);
                var result = client.PostAsync("http://47.110.252.85:8011/API/APP/PowCoinChart", httpContent).Result;
                var d = result.Content.ReadAsStringAsync().Result;
                var data = JsonConvert.DeserializeObject<ApiResult<ChartDatas>>(d);
                return data;
            }
        }
        /// <summary>
        /// 币种列表
        /// </summary>
        /// <param name="CurrencyId"></param>
        private ApiResult<CoinListData> GetPowCoinList()
        {
            using (var client = _httpClientFactory.CreateClient())
            {

                var result = client.PostAsync("http://47.110.252.85:8011/API/APP/PoolCoinList", null).Result;
                var d = result.Content.ReadAsStringAsync().Result;
                var data = JsonConvert.DeserializeObject<ApiResult<CoinListData>>(d);
                return data;
            }
        }
        /// <summary>
        /// 线形图数据
        /// </summary>
        /// <param name="code"></param>
        public ChartDatas GetLineData(string code)
        {
            code = code.ToUpper();
            var lineStrData = _cache.Get<string>(RedisKeyConst.Coin + "_ChartData_" + code);
            if (lineStrData == null)
            {
                CoinList[] CoinListData = null;
                var CoinListStrData = _cache.Get<string>(RedisKeyConst.Coin + "_CoinList");
                if (CoinListStrData == null)
                {
                    var d = GetPowCoinList();
                    if (d.Type != 1)
                    {
                        return null;
                    }
                    CoinListData = d.Data.CoinList;
                    _cache.Set(RedisKeyConst.Coin + "_CoinList", JsonConvert.SerializeObject(CoinListData));
                    _cache.Set("_RMB&USD", d.Data.Exchange.ToString());
                }
                else
                { 
                    CoinListData = JsonConvert.DeserializeObject<CoinList[]>(CoinListStrData);
                }

                var ChartData = GetPowCoinChart(CoinListData.Where(m => m.Code.ToUpper() == code.ToUpper()).Select(m => m.Code).FirstOrDefault());
                if (ChartData.Type == 1)
                {
                    return ChartData.Data;
                }
            }
            var lineData = JsonConvert.DeserializeObject<ChartDatas>(lineStrData);
            return lineData;
        }
        /// <summary>
        /// 理论收益
        /// </summary>
        /// <param name="code"></param>
        public ProfitData GetProfitData(string code)
        {
            code = code.ToUpper();
            ProfitData profitData = new ProfitData();
            var cacheStrData = _cache.Get<string>(RedisKeyConst.Coin + "_Profit_" + code);
            if (cacheStrData == null)
            {
                CoinList[] CoinListData = null;
                var CoinListStrData = _cache.Get<string>(RedisKeyConst.Coin + "_CoinList");
                if (CoinListStrData == null)
                {
                    var d = GetPowCoinList();
                    if (d.Type != 1)
                    {
                        return null;
                    }

                    CoinListData = d.Data.CoinList;
                    _cache.Set(RedisKeyConst.Coin + "_CoinList", JsonConvert.SerializeObject(CoinListData));
                    _cache.Set("_RMB&USD", JsonConvert.SerializeObject(CoinListData));
                    _cache.Set("_RMB&USD", d.Data.Exchange.ToString());
                }
                else
                { 
                    CoinListData = JsonConvert.DeserializeObject<CoinList[]>(CoinListStrData);
                }
                var codeData = CoinListData.Where(m => m.Code.ToUpper() == code).FirstOrDefault();
                if (codeData == null)
                {
                    return null;
                }

                var CoinData = GetPowCoinDetails(codeData.Id);
                if (CoinData.Type != 1)
                {
                    return null;
                }

                var Coin = CoinData.Data;
                profitData = new ProfitData { EstimatedProfit = Coin.EstimatedProfit, ProfitPerHash = Coin.ProfitPerHash };
                _cache.Set(RedisKeyConst.Coin + "_Profit_" + code, JsonConvert.SerializeObject(profitData));
            }
            else
            {
                profitData = JsonConvert.DeserializeObject<ProfitData>(cacheStrData);
            }
            return profitData;
        }
    }
    public class ApiResult<T>
    {
        public int Type { get; set; }
        public string Content { get; set; }
        public T Data { get; set; }
    }
    public class ChartDataList
    {

        public DateTime CreatedTime { get; set; }
        /// <summary>
        /// 算力
        /// </summary>
        public float Hashrate { get; set; }
        /// <summary>
        /// 币价
        /// </summary>
        public float Price { get; set; }
        /// <summary>
        /// 算力单位
        /// </summary>
        public string HashrateUnit { get; set; }
    }
    public class ChartDatas
    {
        public string Exchange { get; set; }
        public ChartDataList[] ChartData { get; set; }
    }
    public class LineData
    {
        public ChartDatas[] ChartData { get; set; }
        /// <summary>
        /// 汇率
        /// </summary>
        public float Exchange { get; set; }
    }
    public class Coin
    {
        /// <summary>
        /// 日理论收益（币）
        /// </summary>
        public float EstimatedProfit { get; set; }
        /// <summary>
        /// 日理论收益算力单位
        /// </summary>
        public string ProfitPerHash { get; set; }
        /// <summary>
        /// 编码
        /// </summary>
        public string Code { get; set; }
        /// <summary>
        /// 币价/美元
        /// </summary>
        public float Price { get; set; }
    }
    public class CoinList
    {
        public int Id { get; set; }
        /// <summary>
        /// 编码
        /// </summary>
        public string Code { get; set; }
    }

    public class CoinListData
    {
        public CoinList[] CoinList { get; set; }
        /// <summary>
        /// 汇率
        /// </summary>
        public double Exchange { get; set; }
    }



    public class ProfitData
    {
        /// <summary>
        /// 日理论收益（币）
        /// </summary>
        public float EstimatedProfit { get; set; }
        /// <summary>
        /// 日理论收益算力单位
        /// </summary>
        public string ProfitPerHash { get; set; }
    }
}
